/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
/**
 * \file
 * \brief Encapsulating the MaCI Interace clients.
 * \author Antti Maula <antti.maula@tkk.fi>
 */
#ifndef _MACI_J2B2CLIENTINTERFACE_HPP_
#define _MACI_J2B2CLIENTINTERFACE_HPP_

// MaCI Interfaces
#include "ImageClient.hpp"
#include "SpeedCtrlClient.hpp"
#include "PositionClient.hpp"
#include "RangingClient.hpp"
#include "JointGroupCtrlClient.hpp"
#include "TextClient.hpp"
#include "BehaviourClient.hpp"
#include "IOClient.hpp"
#include "MaCICtrlClient.hpp"
#include <vector>

/** Macro for backwards compabitility with existing IO card software.
 * \deprecated
 */
#define iIOBoard iIOBoardAD5414


/** Macro for backwards compabitility with existing IO card software.
 * \deprecated
 */
#define KEnabledInterfaceIOBoard KEnabledInterfaceIOBoardAD5414


/** Enabled interfaces.
 */
enum EEnabledInterface {
  KEnabledInterfaceNone                = (0),
  KEnabledInterfaceImageCameraFront    = (1<<0),
  KEnabledInterfaceServoCtrl           = (1<<1),
  KEnabledInterfaceSpeedCtrl           = (1<<2),
  KEnabledInterfacePositionOdometry    = (1<<3),
  KEnabledInterfaceBehaviourCtrl       = (1<<5),
  KEnabledInterfaceRangingLaser        = (1<<6),
  KEnabledInterfaceRangingBumpers      = (1<<7),
  KEnabledInterfaceIOBoardAD5414       = (1<<8),
  KEnabledInterfaceIOBoardESC          = (1<<9),
  KEnabledInterfaceTextToSpeech        = (1<<10),
  KEnabledInterfaceImageCameraExtra    = (1<<11),
  KEnabledInterfaceAll                 = (0xFFFF), // All bits set.
  KEnabledInterfacesForSimulator       = ( (1<<0) |
                                           (1<<1) |
                                           (1<<2) |
                                           (1<<3) |
                                           (1<<5) |
                                           (1<<6) |
                                           (1<<7) 
                                           ),
  KEnabledInterfacesForRealJ2B2        = ( (1<<0) |
                                           (1<<1) |
                                           (1<<2) |
                                           (1<<3) |
                                           (1<<5) |
                                           (1<<6) |
                                           (1<<7) |
                                           (1<<8) |
                                           (1<<9) |
                                           (1<<10)
                                           )
};


/**
 * Constants for joint controller. This controller controls CameraPTU,
 * as well as any User Defined servos. Special 'channel numbers'
 * defines which Servo the command applies to.
 * 
 * This values should be passed as:
 * iServoCtrl->SetPosition( KServo..., yourvalue );
 */
enum EServo { 
  KServoCameraPTUPan = 0,     ///< Camera PTU - Pan
  KServoCameraPTUTilt = 1,    ///< Camera PTU - Tilt
  KServoUserServo_0 = 2,      ///< User defined servo 0 (on Ch 2)
  KServoUserServo_1 = 3,      ///< User defined servo 1 (on Ch 3)
  KServoUserServo_2 = 4,      ///< User defined servo 2 (on Ch 4)
  KServoUserServo_3 = 5       ///< User defined servo 3 (on Ch 5)
};
              

/** J2B2 specific collection of MaCI client interfaces. 
 * 
 * This is not a "Interface" itself, rather just a wrapup of J2B2
 * specific drivers. You can freely edit this file as you wish, it is
 * only provided for your convenience.
 */
class CJ2B2ClientInterface
{
public:
  /** Constructor.
   */
  CJ2B2ClientInterface(gimi::GIMI *aGIMIptr);

  /** Destructor.
   */
  ~CJ2B2ClientInterface();



  /** Open J2B2ClientInterface.
   *
   * This function attempts to Open() J2B2Interface. It locates all
   * requested services and initializes them. If everything went
   * smoothly, the function returns true and devices are directly
   * usable through their stored instance pointers.
   *
   * @param[in] aMaCIGroup      Locate service from this MaCIGroup.
   * @param[in] aEnabledInterfaces This parameter selects the interfaces
   *                            to open. If it is left to default parameter
   *                            'KEnabledInterfaceAll', all J2B2 standard
   *                             devices will be opened. Any subset of opened
   *                            devices can be selected by defining appropriate
   *                            set of bits. For example, to only enable
   *                            'SpeedCtrl' and 'PositionOdometry' you would
   *                            specify:\n
   *                            (KEnabledInterfacePositionOdometry | 
   *                             KEnabledInterfaceSpeedCtrl)
   *
   * @return                    'true' on success, 'false' on any error.
   */
  bool Open(const std::string &aMaCIGroup, 
            const int aEnabledInterfaces = KEnabledInterfaceAll);
  


  /** Close interface.
   *
   * This function closes the interface by calling Close() on all devices.
   *
   * @return                    'true' on success, 'false' on any error.
   */
  bool Close(void);


public: // Variables
  MaCI::Image::CImageClient *iImageCameraFront;             ///< Front camera
  MaCI::Image::CImageClient *iImageCameraExtra;             ///< Extra camera
  MaCI::JointGroupCtrl::CJointGroupCtrlClient *iServoCtrl;  ///< PTU of camera
  MaCI::SpeedCtrl::CSpeedCtrlClient *iMotionCtrl;           ///< motion control
  MaCI::Position::CPositionClient *iPositionOdometry;       ///< Odometry source
  MaCI::Behaviour::CBehaviourClient *iBehaviourCtrl;        ///< Behaviour control
  MaCI::Ranging::CRangingClient *iRangingLaser;             ///< Laser scanner
  MaCI::Ranging::CRangingClient *iRangingBumpers;           ///< Bumpers
  MaCI::IO::CIOClient *iIOBoardAD5414;                      ///< IO Board bound to AD5414-io.
  MaCI::IO::CIOClient *iIOBoardESC;                         ///< IO Board bound to ESC-io. OUT: 8-15, IN: 16-23
  MaCI::Text::CTextClient *iTextToSpeech;                   ///< Text To Speech client.

  

private: // Variables
  gimi::GIMI *iGIMIPtr;                                     ///< GIMI Ptr.
  EEnabledInterface iEnabledInterfaces;
  std::string iMaCIGroup;
  std::vector<MaCI::CMaCI *> iAllClients;
  
private: // Functions
  bool InitializeServices(const MaCI::MaCICtrl::TServiceEntryArray &aServices);
  bool InitializeCamera(const MaCI::MaCICtrl::TServiceEntryArray &aServices);
  bool InitializeControls(const MaCI::MaCICtrl::TServiceEntryArray &aServices);
  bool InitializeInfos(const MaCI::MaCICtrl::TServiceEntryArray &aServices);
  bool InitializeSensors(const MaCI::MaCICtrl::TServiceEntryArray &aServices);

  CJ2B2ClientInterface(const CJ2B2ClientInterface &)
    : iImageCameraFront(),
      iImageCameraExtra(),
      iServoCtrl(),
      iMotionCtrl(),
      iPositionOdometry(),
      iBehaviourCtrl(),
      iRangingLaser(),
      iRangingBumpers(),
      iIOBoardAD5414(),
      iIOBoardESC(),
      iTextToSpeech(),
      iGIMIPtr(),
      iEnabledInterfaces(),
      iMaCIGroup(),
      iAllClients() {}
  CJ2B2ClientInterface &operator=(const CJ2B2ClientInterface &) { return *this; }


};

#endif
